//数组原生具备iterator接口，for...of循环本质上就是调用这个接口产生的遍历器
const arr = ['red', 'green', 'blue'];
let iterator  = arr[Symbol.iterator]();

for(let v of arr) {
  console.log(v); // red green blue
//优点
//有着同for...in一样的简洁语法，但是没有for...in那些缺点。
//不同用于forEach方法，它可以与break、continue和return配合使用。
//提供了遍历所有数据结构的统一操作接口。
//ps：编译后的代码，好长的哦
}

for(let v of iterator) {
  console.log(v); // red green blue
}

//2.可以替代forEach 方法，先有element,再有index
arr.forEach(function (element, index) {
  console.log(element); // red green blue
  // console.log(index);   // 0 1 2
  //这种写法的问题在于，无法中途跳出forEach循环
});

//3.for in 方法，遍历的是index，而for of 得到的是元素
for(let i in arr) {
  console.log(i); //0,1,2 //如果是对象，则for in 得到的是key.
  console.log(arr[i]); //red,green,blue
//for...in循环不仅遍历数字键名，还会遍历手动添加的其他键，甚至包括原型链上的键。
//某些情况下，for...in循环会以任意顺序遍历键名。
//总之，for...in循环主要是为遍历对象而设计的，不适用于遍历数组
}

//for...of循环调用遍历器接口，数组的遍历器接口只返回具有数字索引的属性。
//这一点跟for...in循环也不一样。
let arr1 = [3, 5, 7];
arr.foo = 'hello';

for (let i in arr1) {
  console.log(i); // "0", "1", "2", "foo"
}

for (let i of arr1) {
  console.log(i); //  "3", "5", "7"
}

//类似数组的对象包括:字符串、DOM NodeList对象、arguments对象,这些都可以用for...of
//并不是所有类似数组的对象都具有iterator接口，一个简便的解决方法，就是使用Array.from方法将其转为数组。
let arrayLike = { length: 2, 0: 'a', 1: 'b' };
// 报错
//for (let x of arrayLike) {
//  console.log(x);
//}

// 正确
for (let x of Array.from(arrayLike)) {
  console.log(x);
}
